diff --git a/packages/rulesets/src/oas/__tests__/array-items.test.ts b/packages/rulesets/src/oas/__tests__/array-items.test.ts new file mode 100644 index 000000000..144ca5d6e --- /dev/null +++ b/packages/rulesets/src/oas/__tests__/array-items.test.ts @@ -0,0 +1,81 @@ +import { DiagnosticSeverity } from '@stoplight/types'; + +import testRule from '../../__tests__/__helpers__/tester'; + +testRule('array-items', [ + { + name: 'valid case', + document: { + swagger: '2.0', + securityDefinitions: { + apikey: {}, + }, + paths: { + '/path': { + get: { + security: [ + { + apikey: [], + }, + ], + }, + }, + }, + }, + errors: [], + }, + + { + name: 'array items sibling is present', + document: { + $ref: '#/', + responses: { + 200: { + type: 'array', + items: {}, + }, + 201: { + type: 'array', + items: { + type: 'array', + items: {}, + }, + }, + }, + openapi: '3.0.0', + }, + errors: [], + }, + { + name: 'array items sibling is missing', + document: { + $ref: '#/', + responses: { + 200: { + type: 'array', + }, + 201: { + type: 'array', + items: { + type: 'array', + }, + }, + }, + openapi: '3.0.0', + }, + errors: [ + { + code: 'array-items', + message: 'Schemas with "type: array", require a sibling "items" field', + path: ['responses', '200'], + severity: DiagnosticSeverity.Error, + }, + { + code: 'array-items', + message: 'Schemas with "type: array", require a sibling "items" field', + path: ['responses', '201', 'items'], + severity: DiagnosticSeverity.Error, + }, + ], + }, +]); diff --git a/packages/rulesets/src/oas/index.ts b/packages/rulesets/src/oas/index.ts index 253673754..d59122c2f 100644 --- a/packages/rulesets/src/oas/index.ts +++ b/packages/rulesets/src/oas/index.ts @@ -361,6 +361,18 @@ const ruleset = { function: refSiblings, }, }, + 'array-items': { + formats: [oas3_0], + message: 'Schemas with "type: array", require a sibling "items" field', + severity: 0, + recommended: true, + resolved: false, + given: "$..[?(@.type === 'array')]", + then: { + function: truthy, + field: 'items', + }, + }, 'typed-enum': { description: 'Enum values must respect the specified type.', message: '{{error}}', diff --git a/test-harness/scenarios/require-type-array-items-field.oas3.scenario b/test-harness/scenarios/require-type-array-items-field.oas3.scenario new file mode 100644 index 000000000..a99facf5c --- /dev/null +++ b/test-harness/scenarios/require-type-array-items-field.oas3.scenario @@ -0,0 +1,51 @@ +====test==== +Schemas with "type: array", require a sibling "items" field +====document==== +openapi: 3.0.3 +info: + title: test + description: Test specification file + version: '1.0' + contact: + name: John Doe + url: 'https://example.com' + email: john_doe@example.com + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0' +servers: + - url: 'http://localhost:3000' +tags: + - name: list-endpoint + description: Endpoint for listing objects +paths: + /users: + get: + summary: List Users + operationId: get-users + description: List all Users + tags: + - list-endpoint + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + favoriteColorSets: + type: array + items: + type: array + +====asset:ruleset==== +const { oas } = require('@stoplight/spectral-rulesets'); +module.exports = oas; +====command==== +{bin} lint {document} --ruleset "{asset:ruleset}" +====stdout==== +{document} + 36:27 error array-items Schemas with "type: array", require a sibling "items" field paths./users.get.responses[200].content.application/json.schema.properties.favoriteColorSets.items + +✖ 1 problem (1 error, 0 warnings, 0 infos, 0 hints)