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

actions: reinstate validation of schemas and examples, fixes #1739 #1911

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/validate-examples.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: validate-examples

# Author: @MikeRalphson
# Issue: https://github.com/OAI/OpenAPI-Specification/issues/1739

#
# This workflow validates files in the examples/v2 and /v3 directories
#

# run this on push to any branch and creation of pull-requests
on: [push, pull_request]

jobs:
validate-examples:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1 # checkout repo content
- uses: actions/setup-node@v1 # setup Node.js
with:
node-version: '12.x'
- name: Install dependencies
run: npm i
- name: Validate examples
run: node scripts/validateExamples/index.js

31 changes: 31 additions & 0 deletions .github/workflows/validate-schemas.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: validate-schemas

# Author: @MikeRalphson
# Issue: https://github.com/OAI/OpenAPI-Specification/issues/1739

#
# This workflow validates files in the schemas directory against their
# appropriate meta-schemas
#

# run this on push to any branch and creation of pull-requests
on: [push, pull_request]

jobs:
mdv:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1 # checkout repo content
- uses: actions/setup-node@v1 # setup Node.js
with:
node-version: '12.x'
- name: Install dependencies
run: npm i
- name: Validate schemas
run: |
node scripts/validateSchema/index.js schemas/v1.2/apiDeclaration.json schemas/jsonSchema/draft-04/metaschema.json
node scripts/validateSchema/index.js schemas/v2.0/schema.json schemas/jsonSchema/draft-04/metaschema.json
node scripts/validateSchema/index.js schemas/v3.0/schema.yaml schemas/jsonSchema/draft-04/metaschema.json

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"chai": "^4.3.1",
"mdv": "^1.0.7",
"mocha": "^8.3.0",
"node-readfiles": "^0.2.0",
"yaml": "^1.8.3"
},
"keywords": [
Expand Down
149 changes: 149 additions & 0 deletions schemas/jsonSchema/draft-04/metaschema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"id": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#" }
},
"positiveInteger": {
"type": "integer",
"minimum": 0
},
"positiveIntegerDefault0": {
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
},
"simpleTypes": {
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
},
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}
},
"type": "object",
"properties": {
"id": {
"type": "string"
},
"$schema": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "boolean",
"default": false
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "boolean",
"default": false
},
"maxLength": { "$ref": "#/definitions/positiveInteger" },
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"items": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/schemaArray" }
],
"default": {}
},
"maxItems": { "$ref": "#/definitions/positiveInteger" },
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
"uniqueItems": {
"type": "boolean",
"default": false
},
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
"required": { "$ref": "#/definitions/stringArray" },
"additionalProperties": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"definitions": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/stringArray" }
]
}
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{ "$ref": "#/definitions/simpleTypes" },
{
"type": "array",
"items": { "$ref": "#/definitions/simpleTypes" },
"minItems": 1,
"uniqueItems": true
}
]
},
"format": { "type": "string" },
"allOf": { "$ref": "#/definitions/schemaArray" },
"anyOf": { "$ref": "#/definitions/schemaArray" },
"oneOf": { "$ref": "#/definitions/schemaArray" },
"not": { "$ref": "#" }
},
"dependencies": {
"exclusiveMaximum": [ "maximum" ],
"exclusiveMinimum": [ "minimum" ]
},
"default": {}
}
57 changes: 57 additions & 0 deletions scripts/validateExamples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env node
'use strict';

const fs = require('fs');
const util = require('util');

const yaml = require('yaml');
const rf = require('node-readfiles');
const jsonschema = require('@hyperjump/json-schema');

const schema = {};
schema["v2.0"] = yaml.parse(fs.readFileSync('./schemas/v2.0/schema.json','utf8'));
schema["v3.0"] = yaml.parse(fs.readFileSync('./schemas/v3.0/schema.yaml','utf8'));

jsonschema.add(schema["v2.0"]);
jsonschema.add(schema["v3.0"]);

async function main(path,schema,propName) {
return new Promise(async function(resolve,reject){
let files = await rf(path, { readContents: false, filenameFormat: rf.FULL_PATH });
files = files.sort();
for (let file of files) {
const instanceStr = fs.readFileSync(file,'utf8');
let instanceObj;
try {
instanceObj = yaml.parse(instanceStr,{prettyErrors:true});
}
catch (ex) {
process.exitCode = 1;
console.warn(file,ex.message);
}
if (instanceObj && instanceObj[propName]) {
console.log('Validating',file);
try {
const schemaObj = await jsonschema.get(schema.id);
const result = await jsonschema.validate(schemaObj, instanceObj, jsonschema.DETAILED);
if (!result.valid) {
process.exitCode = 1;
console.warn(file,util.inspect(result.errors, {depth:null}));
}
}
catch (ex) {
process.exitCode = 1;
console.warn(file,ex.message);
}
}
}
resolve(files);
});
}

async function validateExamples(){
await main('./examples/v2.0/',schema["v2.0"],'swagger');
await main('./examples/v3.0/',schema["v3.0"],'openapi');
}

validateExamples();
33 changes: 33 additions & 0 deletions scripts/validateSchema/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env node
'use strict';

const fs = require('fs');
const util = require('util');

const yaml = require('yaml');
const jsonschema = require('@hyperjump/json-schema');

const schema = yaml.parse(fs.readFileSync(process.argv[2],'utf8'));
const metaSchema = yaml.parse(fs.readFileSync(process.argv[3],'utf8'));

async function main() {
jsonschema.add(metaSchema);
const msObj = await jsonschema.get(metaSchema.id);
let result;
try {
result = await jsonschema.validate(msObj, schema, jsonschema.DETAILED);
}
catch (ex) {
result = { valid: false, errors: [ ex ] };
}
if (!result.valid) {
console.warn(util.inspect(result.errors, {depth:null}));
process.exit(1);
}
else {
console.log('OK');
}
}

console.log('Checking',process.argv[2]);
main();