UNPKG

@adobe/jsonschema2md

Version:

Validate and document complex JSON Schemas the easy way.

185 lines (174 loc) 5.59 kB
/* * Copyright 2019 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ const assert = require('assert'); const { root, heading, paragraph, text, link, table, tableRow, tableCell, inlineCode, } = require('mdast-builder'); const unified = require('unified'); const stringify = require('remark-stringify'); const fs = require('fs-extra'); const { report } = require('../lib/keywords'); /* eslint-env mocha */ const expected = [ 'examples', 'allOf', 'json-pointer', 'relative-json-pointer', 'regex', 'uri-template', 'default', ]; const allkeywords = { 'The JSON Schema Core Vocabulary, https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.8.1': [ '$schema', '$vocabulary', '$id', '$anchor', '$ref', '$recursiveRef', '$recursiveAnchor', '$defs', '$comment', ], 'A Vocabulary for Applying Subschemas, https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9': [ 'additionalProperties', 'properties', 'patternProperties', 'unevaluatedProperties', 'additionalItems', 'items', 'unevaluatedItems', 'allOf', 'anyOf', 'oneOf', 'not', 'if', 'then', 'else', 'dependentSchemas', 'contains', 'propertyNames', ], 'Validation Keywords for Any Instance Type, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.1': [ 'type', 'enum', 'const', ], 'Validation Keywords for Numeric Instances, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.2': [ 'multipleOf', 'maximum', 'exclusiveMaximum', 'minimum', 'exclusiveMinimum', ], 'Validation Keywords for Strings, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.3': [ 'maxLength', 'minLength', 'pattern', ], 'Validation Keywords for Arrays, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4': [ 'maxItems', 'minItems', 'uniqueItems', 'maxContains', 'minContains', ], 'Validation Keywords for Objects, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5': [ 'maxProperties', 'minProperties', 'required', 'dependentRequired', ], 'Defined Formats, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7.3': [ 'date-time', 'date', 'time', 'duration', 'email', 'idn-email', 'hostname', 'idn-hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference', 'iri', 'iri-reference', 'uuid', 'uri-template', 'json-pointer', 'relative-json-pointer', 'regex', ], 'A Vocabulary for the Contents of String-Encoded Data, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.8': [ 'contentEncoding', 'contentMediaType', 'contentSchema', ], 'A Vocabulary for Basic Meta-Data Annotations, https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9': [ 'title', 'description', 'default', 'deprecated', 'readOnly', 'writeOnly', 'examples', ], }; after('Generating Schema Coverage Report', () => { const allkeywordsplain = Array.from(new Set(Object .values(allkeywords) .reduce((p, v) => [...p, ...v], []))); const allkeywordssupported = allkeywordsplain .filter(keyword => report().has(keyword)); const overall = Math.floor(100 * allkeywordssupported.length / allkeywordsplain.length); const sections = Object.entries(allkeywords).map(([name, keywords]) => { const [label, url] = name.split(', '); const coverage = Math.floor( 100 * keywords.filter(keyword => report().has(keyword)).length / keywords.length, ); return [ heading(2, text(label)), paragraph([text('Coverage for '), link(url, '', text(label)), text(` is ${coverage}%.`)]), table('left', [ tableRow([ tableCell(text('Keyword')), tableCell(text('Supported')), ]), ...keywords.sort().map(keyword => tableRow([ tableCell(inlineCode(keyword)), tableCell(text(report().has(keyword) ? 'Yes' : 'No')), ])), ]), ]; }).reduce((p, v) => [...p, ...v], []); const mdast = root([ heading(1, text('JSON Schema Spec Coverage Report')), paragraph(text(`This report lists the keywords of the JSON Schema spec that are covered in the tests. The overall coverage is ${overall}%`)), ...sections, ]); const processor = unified() .use(stringify); const output = processor.stringify(mdast); fs.writeFileSync('schemasupport.md', output); const lowerlimit = 50; assert.ok(overall > lowerlimit, `Expected minumum spec coverage of ${lowerlimit}%, got only ${overall}%`); }); describe('Checking JSON Schema Spec coverage', () => { expected.forEach((keyword) => { it(`keyword ${keyword}`, () => { assert.ok(report().has(keyword), `keyword ${keyword} not used in tests`); }); }); });