Skip to content

Commit 7378d50

Browse files
committed
feat: consistent error messages and descriptions
messages are shorter showing what is wrong, descriptions are longer explaining why.
1 parent 7266185 commit 7378d50

21 files changed

+714
-867
lines changed

__tests__/__helpers__/helper.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import { IRuleResult, Spectral, Document, Ruleset, RulesetDefinition } from '@stoplight/spectral-core';
2-
import { httpAndFileResolver } from '@stoplight/spectral-ref-resolver';
3-
import apisYouWontHateRuleset from '../../src/ruleset';
1+
import {
2+
IRuleResult,
3+
Spectral,
4+
Document,
5+
Ruleset,
6+
RulesetDefinition,
7+
} from "@stoplight/spectral-core";
8+
import { httpAndFileResolver } from "@stoplight/spectral-ref-resolver";
9+
import apisYouWontHateRuleset from "../../src/ruleset";
410

5-
export type RuleName = keyof Ruleset['rules'];
11+
export type RuleName = keyof Ruleset["rules"];
612

713
type Scenario = ReadonlyArray<
814
Readonly<{
@@ -15,27 +21,32 @@ type Scenario = ReadonlyArray<
1521

1622
export default (ruleName: RuleName, tests: Scenario): void => {
1723
describe(`Rule ${ruleName}`, () => {
18-
const concurrent = tests.every(test => test.mocks === void 0 || Object.keys(test.mocks).length === 0);
24+
const concurrent = tests.every(
25+
(test) => test.mocks === void 0 || Object.keys(test.mocks).length === 0
26+
);
1927
for (const testCase of tests) {
2028
(concurrent ? it.concurrent : it)(testCase.name, async () => {
2129
const s = createWithRules([ruleName]);
22-
const doc = testCase.document instanceof Document ? testCase.document : JSON.stringify(testCase.document);
30+
const doc =
31+
testCase.document instanceof Document
32+
? testCase.document
33+
: JSON.stringify(testCase.document);
2334
const errors = await s.run(doc);
2435
expect(errors.filter(({ code }) => code === ruleName)).toEqual(
25-
testCase.errors.map(error => expect.objectContaining(error) as unknown),
36+
testCase.errors.map(
37+
(error) => expect.objectContaining(error) as unknown
38+
)
2639
);
2740
});
2841
}
2942
});
3043
};
3144

32-
export function createWithRules(rules: (keyof Ruleset['rules'])[]): Spectral {
45+
export function createWithRules(rules: (keyof Ruleset["rules"])[]): Spectral {
3346
const s = new Spectral({ resolver: httpAndFileResolver });
3447

3548
s.setRuleset({
36-
extends: [
37-
[apisYouWontHateRuleset as RulesetDefinition, 'off'],
38-
],
49+
extends: [[apisYouWontHateRuleset as RulesetDefinition, "off"]],
3950
rules: rules.reduce((obj: Record<string, boolean>, name) => {
4051
obj[name] = true;
4152
return obj;

__tests__/adv-security-schemes-defined.test.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

__tests__/api-health-format.test.ts

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,72 @@
1-
import { DiagnosticSeverity } from '@stoplight/types';
2-
import testRule from './__helpers__/helper';
1+
import { DiagnosticSeverity } from "@stoplight/types";
2+
import testRule from "./__helpers__/helper";
33

44
const template = (contentType: string) => {
55
return {
6-
openapi: '3.1.0',
7-
info: { version: '1.0', contact: {} },
8-
paths: {
6+
openapi: "3.1.0",
7+
info: { version: "1.0", contact: {} },
8+
paths: {
99
"/health": {
10-
"get": {
11-
"summary": "Your health endpoint",
12-
"responses": {
10+
get: {
11+
summary: "Your health endpoint",
12+
responses: {
1313
"200": {
14-
"description": "Error",
15-
"content": {
16-
[contentType]: {}
17-
}
18-
}
19-
}
20-
}
21-
}
22-
}
23-
}
14+
description: "Error",
15+
content: {
16+
[contentType]: {},
17+
},
18+
},
19+
},
20+
},
21+
},
22+
},
23+
};
2424
};
2525

26-
testRule('api-health-format', [
26+
testRule("api-health-format", [
2727
{
28-
name: 'valid case',
29-
document: template('application/vnd.health+json'),
28+
name: "valid case",
29+
document: template("application/vnd.health+json"),
3030
errors: [],
3131
},
3232

3333
{
34-
name: 'invalid case if plain json',
35-
document: template('application/json'),
34+
name: "invalid case if plain json",
35+
document: template("application/json"),
3636
errors: [
3737
{
38-
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.',
39-
path: ['paths', "/health", "get", "responses", "200", "content", "application/json"],
38+
message:
39+
"Health path (`/heath`) SHOULD support Health Check Response Format",
40+
path: [
41+
"paths",
42+
"/health",
43+
"get",
44+
"responses",
45+
"200",
46+
"content",
47+
"application/json",
48+
],
4049
severity: DiagnosticSeverity.Warning,
4150
},
4251
],
4352
},
4453

4554
{
46-
name: 'invalid case if any other mime type',
47-
document: template('text/png'),
55+
name: "invalid case if any other mime type",
56+
document: template("text/png"),
4857
errors: [
4958
{
50-
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.',
51-
path: ['paths', "/health", "get", "responses", "200", "content", "text/png"],
59+
message:
60+
"Health path (`/heath`) SHOULD support Health Check Response Format",
61+
path: [
62+
"paths",
63+
"/health",
64+
"get",
65+
"responses",
66+
"200",
67+
"content",
68+
"text/png",
69+
],
5270
severity: DiagnosticSeverity.Warning,
5371
},
5472
],

__tests__/api-health.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import { DiagnosticSeverity } from '@stoplight/types';
2-
import testRule from './__helpers__/helper';
1+
import { DiagnosticSeverity } from "@stoplight/types";
2+
import testRule from "./__helpers__/helper";
33

4-
testRule('api-health', [
4+
testRule("api-health", [
55
{
6-
name: 'valid case',
6+
name: "valid case",
77
document: {
8-
openapi: '3.1.0',
9-
info: { version: '1.0', contact: {} },
10-
paths: { '/health': {} },
8+
openapi: "3.1.0",
9+
info: { version: "1.0", contact: {} },
10+
paths: { "/health": {} },
1111
},
1212
errors: [],
1313
},
1414

1515
{
16-
name: 'invalid case',
16+
name: "invalid case",
1717
document: {
18-
openapi: '3.1.0',
19-
info: { version: '1.0', contact: {} },
18+
openapi: "3.1.0",
19+
info: { version: "1.0", contact: {} },
2020
paths: {},
2121
},
2222
errors: [
2323
{
24-
message: 'Creating a `/health` endpoint is a simple solution for pull-based monitoring and manually checking the status of an API.',
25-
path: ['paths'],
24+
message: "APIs MUST have a health path (`/health`) defined.",
25+
path: ["paths"],
2626
severity: DiagnosticSeverity.Warning,
2727
},
2828
],

__tests__/api-home-get.test.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
import { DiagnosticSeverity } from '@stoplight/types';
2-
import testRule from './__helpers__/helper';
1+
import { DiagnosticSeverity } from "@stoplight/types";
2+
import testRule from "./__helpers__/helper";
33

4-
testRule('api-home-get', [
4+
testRule("api-home-get", [
55
{
6-
name: 'valid case',
6+
name: "valid case",
77
document: {
8-
openapi: '3.1.0',
9-
info: { version: '1.0' },
10-
paths: {
11-
'/': {
12-
'get': {}
13-
}
8+
openapi: "3.1.0",
9+
info: { version: "1.0" },
10+
paths: {
11+
"/": {
12+
get: {},
13+
},
1414
},
1515
},
1616
errors: [],
1717
},
18-
18+
1919
{
20-
name: 'invalid case',
20+
name: "invalid case",
2121
document: {
22-
openapi: '3.1.0',
23-
info: { version: '1.0' },
22+
openapi: "3.1.0",
23+
info: { version: "1.0" },
2424
paths: {
25-
'/': {}
25+
"/": {},
2626
},
2727
},
2828
errors: [
2929
{
30-
message: "Otherwise people won't know how to get it.",
31-
path: ['paths', '/'],
30+
message: "APIs root path (`/`) MUST have a GET operation.",
31+
path: ["paths", "/"],
3232
severity: DiagnosticSeverity.Warning,
3333
},
3434
],

__tests__/api-home.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import { DiagnosticSeverity } from '@stoplight/types';
2-
import testRule from './__helpers__/helper';
1+
import { DiagnosticSeverity } from "@stoplight/types";
2+
import testRule from "./__helpers__/helper";
33

4-
testRule('api-home', [
4+
testRule("api-home", [
55
{
6-
name: 'valid case',
6+
name: "valid case",
77
document: {
8-
openapi: '3.1.0',
9-
info: { version: '1.0' },
10-
paths: { '/': {} },
8+
openapi: "3.1.0",
9+
info: { version: "1.0" },
10+
paths: { "/": {} },
1111
},
1212
errors: [],
1313
},
1414

1515
{
16-
name: 'invalid case',
16+
name: "invalid case",
1717
document: {
18-
openapi: '3.1.0',
19-
info: { version: '1.0' },
18+
openapi: "3.1.0",
19+
info: { version: "1.0" },
2020
paths: {},
2121
},
2222
errors: [
2323
{
24-
message: 'Stop forcing all API consumers to visit documentation for basic interactions when the API could do that itself.',
25-
path: ['paths'],
24+
message: "APIs MUST have a root path (`/`) defined.",
25+
path: ["paths"],
2626
severity: DiagnosticSeverity.Warning,
2727
},
2828
],

0 commit comments

Comments
 (0)