Skip to content

Commit

Permalink
feat: consistent error messages and descriptions
Browse files Browse the repository at this point in the history
messages are shorter showing what is wrong, descriptions are longer explaining why.
  • Loading branch information
philsturgeon committed Dec 29, 2022
1 parent 7266185 commit 7378d50
Show file tree
Hide file tree
Showing 21 changed files with 714 additions and 867 deletions.
33 changes: 22 additions & 11 deletions __tests__/__helpers__/helper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { IRuleResult, Spectral, Document, Ruleset, RulesetDefinition } from '@stoplight/spectral-core';
import { httpAndFileResolver } from '@stoplight/spectral-ref-resolver';
import apisYouWontHateRuleset from '../../src/ruleset';
import {
IRuleResult,
Spectral,
Document,
Ruleset,
RulesetDefinition,
} from "@stoplight/spectral-core";
import { httpAndFileResolver } from "@stoplight/spectral-ref-resolver";
import apisYouWontHateRuleset from "../../src/ruleset";

export type RuleName = keyof Ruleset['rules'];
export type RuleName = keyof Ruleset["rules"];

type Scenario = ReadonlyArray<
Readonly<{
Expand All @@ -15,27 +21,32 @@ type Scenario = ReadonlyArray<

export default (ruleName: RuleName, tests: Scenario): void => {
describe(`Rule ${ruleName}`, () => {
const concurrent = tests.every(test => test.mocks === void 0 || Object.keys(test.mocks).length === 0);
const concurrent = tests.every(
(test) => test.mocks === void 0 || Object.keys(test.mocks).length === 0
);
for (const testCase of tests) {
(concurrent ? it.concurrent : it)(testCase.name, async () => {
const s = createWithRules([ruleName]);
const doc = testCase.document instanceof Document ? testCase.document : JSON.stringify(testCase.document);
const doc =
testCase.document instanceof Document
? testCase.document
: JSON.stringify(testCase.document);
const errors = await s.run(doc);
expect(errors.filter(({ code }) => code === ruleName)).toEqual(
testCase.errors.map(error => expect.objectContaining(error) as unknown),
testCase.errors.map(
(error) => expect.objectContaining(error) as unknown
)
);
});
}
});
};

export function createWithRules(rules: (keyof Ruleset['rules'])[]): Spectral {
export function createWithRules(rules: (keyof Ruleset["rules"])[]): Spectral {
const s = new Spectral({ resolver: httpAndFileResolver });

s.setRuleset({
extends: [
[apisYouWontHateRuleset as RulesetDefinition, 'off'],
],
extends: [[apisYouWontHateRuleset as RulesetDefinition, "off"]],
rules: rules.reduce((obj: Record<string, boolean>, name) => {
obj[name] = true;
return obj;
Expand Down
37 changes: 0 additions & 37 deletions __tests__/adv-security-schemes-defined.test.ts

This file was deleted.

76 changes: 47 additions & 29 deletions __tests__/api-health-format.test.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,72 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/helper';
import { DiagnosticSeverity } from "@stoplight/types";
import testRule from "./__helpers__/helper";

const template = (contentType: string) => {
return {
openapi: '3.1.0',
info: { version: '1.0', contact: {} },
paths: {
openapi: "3.1.0",
info: { version: "1.0", contact: {} },
paths: {
"/health": {
"get": {
"summary": "Your health endpoint",
"responses": {
get: {
summary: "Your health endpoint",
responses: {
"200": {
"description": "Error",
"content": {
[contentType]: {}
}
}
}
}
}
}
}
description: "Error",
content: {
[contentType]: {},
},
},
},
},
},
},
};
};

testRule('api-health-format', [
testRule("api-health-format", [
{
name: 'valid case',
document: template('application/vnd.health+json'),
name: "valid case",
document: template("application/vnd.health+json"),
errors: [],
},

{
name: 'invalid case if plain json',
document: template('application/json'),
name: "invalid case if plain json",
document: template("application/json"),
errors: [
{
message: 'Use existing standards (and draft standards) wherever possible, like the draft standard for health checks: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check.',
path: ['paths', "/health", "get", "responses", "200", "content", "application/json"],
message:
"Health path (`/heath`) SHOULD support Health Check Response Format",
path: [
"paths",
"/health",
"get",
"responses",
"200",
"content",
"application/json",
],
severity: DiagnosticSeverity.Warning,
},
],
},

{
name: 'invalid case if any other mime type',
document: template('text/png'),
name: "invalid case if any other mime type",
document: template("text/png"),
errors: [
{
message: 'Use existing standards (and draft standards) wherever possible, like the draft standard for health checks: https://datatracker.ietf.org/doc/html/draft-inadarei-api-health-check.',
path: ['paths', "/health", "get", "responses", "200", "content", "text/png"],
message:
"Health path (`/heath`) SHOULD support Health Check Response Format",
path: [
"paths",
"/health",
"get",
"responses",
"200",
"content",
"text/png",
],
severity: DiagnosticSeverity.Warning,
},
],
Expand Down
24 changes: 12 additions & 12 deletions __tests__/api-health.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/helper';
import { DiagnosticSeverity } from "@stoplight/types";
import testRule from "./__helpers__/helper";

testRule('api-health', [
testRule("api-health", [
{
name: 'valid case',
name: "valid case",
document: {
openapi: '3.1.0',
info: { version: '1.0', contact: {} },
paths: { '/health': {} },
openapi: "3.1.0",
info: { version: "1.0", contact: {} },
paths: { "/health": {} },
},
errors: [],
},

{
name: 'invalid case',
name: "invalid case",
document: {
openapi: '3.1.0',
info: { version: '1.0', contact: {} },
openapi: "3.1.0",
info: { version: "1.0", contact: {} },
paths: {},
},
errors: [
{
message: 'Creating a `/health` endpoint is a simple solution for pull-based monitoring and manually checking the status of an API.',
path: ['paths'],
message: "APIs MUST have a health path (`/health`) defined.",
path: ["paths"],
severity: DiagnosticSeverity.Warning,
},
],
Expand Down
34 changes: 17 additions & 17 deletions __tests__/api-home-get.test.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/helper';
import { DiagnosticSeverity } from "@stoplight/types";
import testRule from "./__helpers__/helper";

testRule('api-home-get', [
testRule("api-home-get", [
{
name: 'valid case',
name: "valid case",
document: {
openapi: '3.1.0',
info: { version: '1.0' },
paths: {
'/': {
'get': {}
}
openapi: "3.1.0",
info: { version: "1.0" },
paths: {
"/": {
get: {},
},
},
},
errors: [],
},

{
name: 'invalid case',
name: "invalid case",
document: {
openapi: '3.1.0',
info: { version: '1.0' },
openapi: "3.1.0",
info: { version: "1.0" },
paths: {
'/': {}
"/": {},
},
},
errors: [
{
message: "Otherwise people won't know how to get it.",
path: ['paths', '/'],
message: "APIs root path (`/`) MUST have a GET operation.",
path: ["paths", "/"],
severity: DiagnosticSeverity.Warning,
},
],
Expand Down
24 changes: 12 additions & 12 deletions __tests__/api-home.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { DiagnosticSeverity } from '@stoplight/types';
import testRule from './__helpers__/helper';
import { DiagnosticSeverity } from "@stoplight/types";
import testRule from "./__helpers__/helper";

testRule('api-home', [
testRule("api-home", [
{
name: 'valid case',
name: "valid case",
document: {
openapi: '3.1.0',
info: { version: '1.0' },
paths: { '/': {} },
openapi: "3.1.0",
info: { version: "1.0" },
paths: { "/": {} },
},
errors: [],
},

{
name: 'invalid case',
name: "invalid case",
document: {
openapi: '3.1.0',
info: { version: '1.0' },
openapi: "3.1.0",
info: { version: "1.0" },
paths: {},
},
errors: [
{
message: 'Stop forcing all API consumers to visit documentation for basic interactions when the API could do that itself.',
path: ['paths'],
message: "APIs MUST have a root path (`/`) defined.",
path: ["paths"],
severity: DiagnosticSeverity.Warning,
},
],
Expand Down
Loading

0 comments on commit 7378d50

Please sign in to comment.