Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(ruleset): improve then validation #1144

Merged
merged 11 commits into from
May 14, 2020
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = true
[*]
charset = utf-8

[*.{ts,js,yaml,scenario,md}]
[*.{ts,js,yaml,yml,json,scenario,md}]
indent_style = space
indent_size = 2

Expand Down
3 changes: 3 additions & 0 deletions karma-jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ test.each = input => (name: string, fn: Function) => {
}
}
};

// @ts-ignore
describe.each = test.each;
6 changes: 3 additions & 3 deletions src/__tests__/linter.jest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { httpAndFileResolver } from '../resolvers/http-and-file';
import { readRuleset } from '../rulesets';
import { setFunctionContext } from '../rulesets/evaluators';
import oasDocumentSchema from '../rulesets/oas/functions/oasDocumentSchema';
import { Spectral } from '../spectral';
import { IFunctionResult, Spectral } from '../spectral';
import { IRuleset, RulesetExceptionCollection } from '../types/ruleset';

const customFunctionOASRuleset = path.join(__dirname, './__fixtures__/custom-functions-oas-ruleset.json');
Expand Down Expand Up @@ -257,7 +257,7 @@ console.log(this.cache.get('test') || this.cache.set('test', []).get('test'));
it('should handle basic example', async () => {
spectral.setFunctions({
[fnName]() {
return new Promise(resolve => {
return new Promise<IFunctionResult[]>(resolve => {
setTimeout(resolve, 200, [
{
message: 'Error reported by async fn',
Expand Down Expand Up @@ -289,7 +289,7 @@ console.log(this.cache.get('test') || this.cache.set('test', []).get('test'));
it('should handle rejections', async () => {
spectral.setFunctions({
[fnName]() {
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
setTimeout(reject, 1000, new Error('Some unknown error'));
});
},
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/linter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('linter', () => {
const message = '4xx responses require a description';

spectral.setFunctions({
func1: val => {
func1: (val: unknown) => {
if (!val) {
return [
{
Expand Down
38 changes: 0 additions & 38 deletions src/functions/__tests__/casing.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { AssertionError } from 'assert';
import { casing, CasingType } from '../casing';

function runCasing(target: unknown, type: CasingType, disallowDigits?: boolean, separator?: any) {
Expand All @@ -20,10 +19,6 @@ describe('casing', () => {
expect(runCasing('', CasingType.camel)).toBeUndefined();
});

test('given unknown case type should return nothing', () => {
expect(() => runCasing('2', 'foo' as any)).toThrowError(AssertionError);
});

describe('casing type', () => {
describe('flat', () => {
const invalid = ['foo_test', 'Foo', '123', '1d', 'foo-bar'];
Expand Down Expand Up @@ -220,39 +215,6 @@ describe('casing', () => {
});

describe('casing with custom separator configuration', () => {
describe('parameters validation', () => {
const casingTypes = Object.keys(CasingType);

test.each([...casingTypes])(
'with "%s" type - throws when allowLeadingSeparator option is used without specifying separator',
type => {
expect(() =>
runCasing('irrelevant value', CasingType[type], undefined, { char: undefined, allowLeading: true }),
).toThrow(AssertionError);
},
);

const invalidSepLengthCombinations = Object.values(casingTypes).reduce<Array<[string, number]>>(
(combinations, type) => {
for (const len of [0, 2, 3, 17]) {
combinations.push([type, len]);
}

return combinations;
},
[],
);

test.each(invalidSepLengthCombinations)(
'with type "%s" - throws when separator value is "%i" (not exactly one char long)',
(type, len) => {
expect(() => runCasing('irrelevant value', CasingType[type], undefined, { char: '-'.repeat(len) })).toThrow(
AssertionError,
);
},
);
});

const baseData: Array<[string, string, string, string]> = [[CasingType.flat, 'flat', 'flat01', 'Nope']];

const testCases: Array<[string, boolean, string, boolean, string, string, string]> = [];
Expand Down
2 changes: 1 addition & 1 deletion src/functions/__tests__/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Optional } from '@stoplight/types';
import { JSONSchema4, JSONSchema6 } from 'json-schema';
import { schema } from '../schema';

function runSchema(target: any, schemaObj: object, oasVersion?: Optional<number>) {
function runSchema(target: any, schemaObj: object, oasVersion?: Optional<2 | 3 | 3.1>) {
return schema(target, { schema: schemaObj, oasVersion }, { given: [] }, { given: null, original: null } as any);
}

Expand Down
4 changes: 2 additions & 2 deletions src/functions/alphabetical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const getUnsortedItems = <T>(arr: T[], compareFn: (a: T, B: T) => number): null
return null;
};

export const alphabetical: IFunction<IAlphaRuleOptions> = (targetVal, opts, paths, { documentInventory }) => {
export const alphabetical: IFunction<IAlphaRuleOptions | null> = (targetVal, opts, paths, { documentInventory }) => {
const results: IFunctionResult[] = [];

if (!isObject(targetVal)) {
Expand All @@ -49,7 +49,7 @@ export const alphabetical: IFunction<IAlphaRuleOptions> = (targetVal, opts, path
return results;
}

const { keyedBy } = opts;
const keyedBy = opts?.keyedBy;

const unsortedItems = getUnsortedItems<unknown>(
targetArray,
Expand Down
23 changes: 0 additions & 23 deletions src/functions/casing.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Dictionary } from '@stoplight/types';
import { AssertionError } from 'assert';
import { escapeRegExp } from 'lodash';
import { IFunction } from '../types';

Expand Down Expand Up @@ -37,8 +36,6 @@ export const casing: IFunction<ICasingOptions> = (targetVal, opts) => {
return;
}

assertValidOptions(opts);

const casingValidator = buildFrom(CASES[opts.type], opts);

if (casingValidator.test(targetVal)) {
Expand All @@ -52,26 +49,6 @@ export const casing: IFunction<ICasingOptions> = (targetVal, opts) => {
];
};

function assertValidOptions(opts: ICasingOptions): asserts opts is ICasingOptions {
if (!(opts.type in CASES)) {
throw new AssertionError({ message: `Invalid '${opts.type}' type value.` });
}

if (opts.separator === undefined) {
return;
}

if (opts.separator.allowLeading !== undefined && opts.separator.char === undefined) {
throw new AssertionError({
message: "'separator.allowLeading' can only be valued when 'separator.char' is defined.",
});
}

if (opts.separator.char.length !== 1) {
throw new AssertionError({ message: "When valued, 'separator.char' should only be one character long." });
}
}

const DIGITS_PATTERN = '0-9';

const buildFrom = (basePattern: string, overrides: ICasingOptions): RegExp => {
Expand Down
2 changes: 1 addition & 1 deletion src/functions/schema-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface ISchemaPathOptions {
// the `path.to.prop` to field, or special `@key` value to target keys for matched `given` object
field?: string;
// The oasVersion, either 2 or 3 for OpenAPI Spec versions, could also be 3.1 or a larger number if there's a need for it, otherwise JSON Schema
oasVersion?: Optional<number>;
oasVersion?: Optional<2 | 3 | 3.1>;
allErrors?: boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion src/functions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface ISchemaFunction extends IFunction<ISchemaOptions> {
export interface ISchemaOptions {
schema: object;
// The oasVersion, either 2 or 3 for OpenAPI Spec versions, could also be 3.1 or a larger number if there's a need for it, otherwise JSON Schema
oasVersion?: Optional<number>;
oasVersion?: Optional<2 | 3 | 3.1>;
allErrors?: boolean;
ajv?: ValidateFunction;

Expand Down
Loading