Skip to content

Commit

Permalink
feat: add an option to set rules that allow complete reset
Browse files Browse the repository at this point in the history
  • Loading branch information
casserni committed Dec 3, 2018
1 parent fb72fc4 commit 35bbf42
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 11 deletions.
123 changes: 123 additions & 0 deletions src/__tests__/spectral.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,129 @@ describe('spectral', () => {
expect(expectedCustomRuleSet).toEqual(givenCustomRuleSet);
});

// Assures: https://stoplightio.atlassian.net/browse/SL-789
test('setting rules with opts should update/append the current ruleset', () => {
const ruleset = {
rules: {
format: {
rule1: {
type: RuleType.STYLE,
function: RuleFunction.TRUTHY,
path: '$',
enabled: true,
summary: '',
input: {
properties: 'something',
},
},
},
},
};
// deep copy
const s = new Spectral({ rulesets: [ruleset] });

s.setRules([
{
rules: {
differentFormat: {
rule2: {
type: RuleType.STYLE,
function: RuleFunction.TRUTHY,
path: '$',
enabled: true,
summary: '',
input: {
properties: 'a different rule',
},
},
},
},
},
]);

expect(s.getRules()).toHaveLength(2);

s.setRules(
[
{
rules: {
format: {
rule1: false,
},
},
},
],
{ includeCurrent: true }
);

expect(s.getRules()).toHaveLength(2);
});

// Assures: https://stoplightio.atlassian.net/browse/SL-789
test('setting rules without includeCurren opts should overwrite the current ruleset', () => {
const ruleset = {
rules: {
format: {
rule1: {
type: RuleType.STYLE,
function: RuleFunction.TRUTHY,
path: '$',
enabled: true,
summary: '',
input: {
properties: 'something',
},
},
},
},
};
// deep copy
const s = new Spectral({ rulesets: [ruleset] });

s.setRules(
[
{
rules: {
differentFormat: {
rule2: {
type: RuleType.STYLE,
function: RuleFunction.TRUTHY,
path: '$',
enabled: true,
summary: '',
input: {
properties: 'a different rule',
},
},
},
},
},
],
{ includeCurrent: false }
);

expect(s.getRules()).toHaveLength(1);
expect(s.getRules()).toMatchInlineSnapshot(`
Array [
Object {
"apply": [Function],
"format": "differentFormat",
"name": "rule2",
"rule": Object {
"enabled": true,
"function": "truthy",
"input": Object {
"properties": "a different rule",
},
"path": "$",
"summary": "",
"type": "style",
},
},
]
`);
});

// Assures: https://stoplightio.atlassian.net/browse/SL-787
test('given a ruleset with two identical rules under two distinct formats should not collide', () => {
const rulesets = [
Expand Down
45 changes: 34 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class Spectral {
// @ts-ignore
private _rulesets: types.IRuleset[] = [];

private _functions: IFunctionStore = {};
private _functions: IFunctionStore = defaultFunctions;

constructor(opts: ISpectralOpts) {
this.setRules(opts.rulesets);
Expand All @@ -89,21 +89,23 @@ export class Spectral {
return rules;
}

public setRules(rulesets: types.IRuleset[]) {
this._rulesets = merge([], rulesets);
this._functions = { ...defaultFunctions, ...this._rulesetsToFunctions(this._rulesets) };
this._rulesByIndex = this._rulesetsToRules(this._rulesets, this._rulesByIndex, this._functions);
public setRules(
rulesets: types.IRuleset[],
opts: { includeCurrent: boolean } = { includeCurrent: true }
) {
const { rulesets: rSets, functionStore, ruleStore } = this._parseRuleSets(rulesets, opts);

this._rulesets = rSets;
this._functions = functionStore;
this._rulesByIndex = ruleStore;
}

public run(opts: IRunOpts): types.IRuleResult[] {
const { target, rulesets = [] } = opts;

let ruleStore = this._rulesByIndex;

if (rulesets.length) {
const functionStore = { ...this._functions, ...this._rulesetsToFunctions(rulesets) };
ruleStore = this._rulesetsToRules(rulesets, ruleStore, functionStore);
}
const ruleStore = rulesets.length
? this._parseRuleSets(rulesets, { includeCurrent: true }).ruleStore
: this._rulesByIndex;

return target ? this.runAllLinters(ruleStore, opts) : [];
}
Expand Down Expand Up @@ -181,6 +183,27 @@ export class Spectral {
return ruleEntry.apply(opt);
}

private _parseRuleSets(
rulesets: types.IRuleset[],
opts: { includeCurrent: boolean } = { includeCurrent: true }
): { rulesets: types.IRuleset[]; functionStore: IFunctionStore; ruleStore: IRuleStore } {
const rSets = merge([], rulesets);

let functionStore = opts.includeCurrent ? this._functions : defaultFunctions;
let ruleStore = opts.includeCurrent ? this._rulesByIndex : {};

if (rSets.length) {
functionStore = { ...functionStore, ...this._rulesetsToFunctions(rulesets) };
ruleStore = this._rulesetsToRules(rulesets, ruleStore, functionStore);
}

return {
rulesets: rSets,
functionStore,
ruleStore,
};
}

private _parseRuleDefinition(
{ name, format, rule }: { name: string; format: string; rule: types.Rule },
functionStore: IFunctionStore = {}
Expand Down

0 comments on commit 35bbf42

Please sign in to comment.