Skip to content

Commit

Permalink
docs(schema): list all keywords supported (and not supported)
Browse files Browse the repository at this point in the history
the new `schemasupport.md` file will be generated automatically after each test run and list all keywords encountered in a test

fixes #100
  • Loading branch information
trieloff committed Dec 11, 2019
1 parent d786c34 commit c6fbe81
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 2 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ Documenting and validating complex JSON Schemas can be hard. This tool makes it

These tools have been introduced by Adobe to document Adobe's Experience Data Models (XDM), but can be used for other JSON Schema documents, too.

## JSON Schema Support

`jsonschema2md` is developed against JSON Schema `2019-09`, but not the full vocabulary is supported. Please check the [detailed list of JSON Schema keywords supported by `jsonschema2md`](schemasupport.md). This list is updated by our tests.

## Requirements

- `npm` version 3.10.8 or up
- `node` v8 or up
- `node` v10 or up

## Example Output

Expand Down
24 changes: 24 additions & 0 deletions lib/keywords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 used = new Set();

function keyword(str) {
used.add(str[0]);
return str.join('');
}

function report() {
return used;
}


module.exports = { keyword, report };
3 changes: 2 additions & 1 deletion lib/schemaProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const ghslugger = require('github-slugger');
const { basename, dirname, resolve } = require('path');
const { formatmeta } = require('./formatInfo');
const symbols = require('./symbols');
const { keyword } = require('./keywords');

const myslug = Symbol('myslug');

Expand Down Expand Up @@ -99,7 +100,7 @@ const handler = ({
}

const retval = Reflect.get(target, prop, receiver);
if (retval === undefined && prop === 'examples' && !receiver[symbols.parent]) {
if (retval === undefined && prop === keyword`examples` && !receiver[symbols.parent]) {
return loadExamples(receiver[symbols.filename], 1);
}
if (typeof retval === 'object') {
Expand Down
148 changes: 148 additions & 0 deletions schemasupport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# JSON Schema Spec Coverage Report

This report lists the keywords of the JSON Schema spec that are covered in the tests. The overall coverage is 1%

## The JSON Schema Core Vocabulary

Coverage for [The JSON Schema Core Vocabulary](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.8.1) is 0%.

| Keyword | Supported |
| :----------------- | --------- |
| `$anchor` | No |
| `$comment` | No |
| `$defs` | No |
| `$id` | No |
| `$recursiveAnchor` | No |
| `$recursiveRef` | No |
| `$ref` | No |
| `$schema` | No |
| `$vocabulary` | No |

## A Vocabulary for Applying Subschemas

Coverage for [A Vocabulary for Applying Subschemas](https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9) is 0%.

| Keyword | Supported |
| :---------------------- | --------- |
| `additionalItems` | No |
| `additionalProperties` | No |
| `allOf` | No |
| `anyOf` | No |
| `contains` | No |
| `dependentSchemas` | No |
| `else` | No |
| `if` | No |
| `items` | No |
| `not` | No |
| `oneOf` | No |
| `patternProperties` | No |
| `properties` | No |
| `propertyNames` | No |
| `then` | No |
| `unevaluatedItems` | No |
| `unevaluatedProperties` | No |

## Validation Keywords for Any Instance Type

Coverage for [Validation Keywords for Any Instance Type](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.1) is 0%.

| Keyword | Supported |
| :------ | --------- |
| `const` | No |
| `enum` | No |
| `type` | No |

## Validation Keywords for Numeric Instances

Coverage for [Validation Keywords for Numeric Instances](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.2) is 0%.

| Keyword | Supported |
| :----------------- | --------- |
| `exclusiveMaximum` | No |
| `exclusiveMinimum` | No |
| `maximum` | No |
| `minimum` | No |
| `multipleOf` | No |

## Validation Keywords for Strings

Coverage for [Validation Keywords for Strings](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.3) is 0%.

| Keyword | Supported |
| :---------- | --------- |
| `maxLength` | No |
| `minLength` | No |
| `pattern` | No |

## Validation Keywords for Arrays

Coverage for [Validation Keywords for Arrays](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.4) is 0%.

| Keyword | Supported |
| :------------ | --------- |
| `maxContains` | No |
| `maxItems` | No |
| `minContains` | No |
| `minItems` | No |
| `uniqueItems` | No |

## Validation Keywords for Objects

Coverage for [Validation Keywords for Objects](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.6.5) is 0%.

| Keyword | Supported |
| :------------------ | --------- |
| `dependentRequired` | No |
| `maxProperties` | No |
| `minProperties` | No |
| `required` | No |

## Defined Formats

Coverage for [Defined Formats](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7.3) is 0%.

| Keyword | Supported |
| :---------------------- | --------- |
| `date` | No |
| `date-time` | No |
| `duration` | No |
| `email` | No |
| `hostname` | No |
| `idn-email` | No |
| `idn-hostname` | No |
| `ipv4` | No |
| `ipv6` | No |
| `iri` | No |
| `iri-reference` | No |
| `json-pointer` | No |
| `regex` | No |
| `relative-json-pointer` | No |
| `time` | No |
| `uri` | No |
| `uri-reference` | No |
| `uri-template` | No |
| `uuid` | No |

## A Vocabulary for the Contents of String-Encoded Data

Coverage for [A Vocabulary for the Contents of String-Encoded Data](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.8) is 0%.

| Keyword | Supported |
| :----------------- | --------- |
| `contentEncoding` | No |
| `contentMediaType` | No |
| `contentSchema` | No |

## A Vocabulary for Basic Meta-Data Annotations

Coverage for [A Vocabulary for Basic Meta-Data Annotations](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9) is 14%.

| Keyword | Supported |
| :------------ | --------- |
| `default` | No |
| `deprecated` | No |
| `description` | No |
| `examples` | Yes |
| `readOnly` | No |
| `title` | No |
| `writeOnly` | No |
179 changes: 179 additions & 0 deletions test/zSchemaCoverage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* 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',
];

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 = 10;
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`);
});
});
});

0 comments on commit c6fbe81

Please sign in to comment.