Skip to content

Commit

Permalink
fix(ns-openapi-3-0): provide missing reference metadata (#2987)
Browse files Browse the repository at this point in the history
Refs #2980
  • Loading branch information
char0n authored Jul 25, 2023
1 parent 6f8174c commit d7cc458
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 1 deletion.
11 changes: 11 additions & 0 deletions packages/apidom-ns-openapi-3-0/src/refractor/specification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@ import HeaderExampleVisitor from './visitors/open-api-3-0/header/ExampleVisitor'
import HeaderExamplesVisitor from './visitors/open-api-3-0/header/ExamplesVisitor';
import HeaderContentVisitor from './visitors/open-api-3-0/header/ContentVisitor';
import SchemaVisitor from './visitors/open-api-3-0/schema';
import SchemaAllOfVisitor from './visitors/open-api-3-0/schema/AllOfVisitor';
import SchemaAnyOfVisitor from './visitors/open-api-3-0/schema/AnyOfVisitor';
import SchemaOneOfVisitor from './visitors/open-api-3-0/schema/OneOfVisitor';
import SchemaDependenciesVisitor from './visitors/open-api-3-0/schema/DependenciesVisitor';
import SchemaItemsVisitor from './visitors/open-api-3-0/schema/ItemsVisitor';
import SchemaPropertiesVisitor from './visitors/open-api-3-0/schema/PropertiesVisitor';
import SchemaPatternPropertiesVisitor from './visitors/open-api-3-0/schema/PatternPropertiesVisitor';
import SchemaTypeVisitor from './visitors/open-api-3-0/schema/TypeVisitor';
import SchemaNullableVisitor from './visitors/open-api-3-0/schema/NullableVisitor';
import SchemaWriteOnlyVisitor from './visitors/open-api-3-0/schema/WriteOnlyVisitor';
Expand Down Expand Up @@ -178,10 +183,16 @@ const SchemaSpecification = {
fixedFields: {
...schemaInheritedFixedFields,
// validation vocabulary
// validation keywords for any instance type
allOf: SchemaAllOfVisitor,
anyOf: SchemaAnyOfVisitor,
oneOf: SchemaOneOfVisitor,
// validation keywords for arrays
items: SchemaItemsVisitor,
// Validation keywords for objects
dependencies: SchemaDependenciesVisitor,
properties: SchemaPropertiesVisitor,
patternProperties: SchemaPatternPropertiesVisitor,
// validation keywords for any instance type
type: SchemaTypeVisitor,
// OpenAPI vocabulary
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import stampit from 'stampit';
import { ObjectElement } from '@swagger-api/apidom-core';
import { specificationObj as JSONSchemaDraft4Specification } from '@swagger-api/apidom-ns-json-schema-draft-4';

import ReferenceElement from '../../../../elements/Reference';
import { isReferenceElement } from '../../../../predicates';

const { dependencies: JSONSchemaDependenciesVisitor } =
JSONSchemaDraft4Specification.visitors.document.objects.JSONSchema.fixedFields;

const DependenciesVisitor = stampit(JSONSchemaDependenciesVisitor, {
methods: {
ObjectElement(objectElement: ObjectElement) {
// @ts-ignore
const result = JSONSchemaDependenciesVisitor.compose.methods.ObjectElement.call(
this,
objectElement,
);

this.element.filter(isReferenceElement).forEach((referenceElement: ReferenceElement) => {
referenceElement.setMetaProperty('referenced-element', 'schema');
});

return result;
},
},
});

export default DependenciesVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import stampit from 'stampit';
import { ObjectElement } from '@swagger-api/apidom-core';
import { specificationObj as JSONSchemaDraft4Specification } from '@swagger-api/apidom-ns-json-schema-draft-4';

import ReferenceElement from '../../../../elements/Reference';
import { isReferenceElement } from '../../../../predicates';

const { patternProperties: JSONSchemaPatternPropertiesVisitor } =
JSONSchemaDraft4Specification.visitors.document.objects.JSONSchema.fixedFields;

const PatternPropertiesVisitor = stampit(JSONSchemaPatternPropertiesVisitor, {
methods: {
ObjectElement(objectElement: ObjectElement) {
// @ts-ignore
const result = JSONSchemaPatternPropertiesVisitor.compose.methods.ObjectElement.call(
this,
objectElement,
);

this.element.filter(isReferenceElement).forEach((referenceElement: ReferenceElement) => {
referenceElement.setMetaProperty('referenced-element', 'schema');
});

return result;
},
},
});

export default PatternPropertiesVisitor;
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`refractor elements SchemaElement given allOf keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ArrayElement
(ReferenceElement
(MemberElement
(StringElement)
(StringElement))))))
`;

exports[`refractor elements SchemaElement given anyOf keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ArrayElement
(ReferenceElement
(MemberElement
(StringElement)
(StringElement))))))
`;

exports[`refractor elements SchemaElement given dependencies keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(ReferenceElement
(MemberElement
(StringElement)
(StringElement)))))))
`;

exports[`refractor elements SchemaElement given embedded SchemaElements should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
Expand Down Expand Up @@ -27,6 +62,43 @@ exports[`refractor elements SchemaElement given items keyword in form of object
(SchemaElement)))
`;

exports[`refractor elements SchemaElement given oneOf keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ArrayElement
(ReferenceElement
(MemberElement
(StringElement)
(StringElement))))))
`;

exports[`refractor elements SchemaElement given patternProperties keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(ReferenceElement
(MemberElement
(StringElement)
(StringElement)))))))
`;

exports[`refractor elements SchemaElement given properties keyword with reference should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
(StringElement)
(ObjectElement
(MemberElement
(StringElement)
(ReferenceElement
(MemberElement
(StringElement)
(StringElement)))))))
`;

exports[`refractor elements SchemaElement should refract to semantic ApiDOM tree 1`] = `
(SchemaElement
(MemberElement
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect } from 'chai';
import { expect, assert } from 'chai';
import { sexprs } from '@swagger-api/apidom-core';

import { SchemaElement } from '../../../../src';
Expand Down Expand Up @@ -81,6 +81,108 @@ describe('refractor', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});
});

context('given allOf keyword with reference', function () {
const schemaElement = SchemaElement.refract({
allOf: [{ $ref: '#/path/to/schema' }],
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.allOf?.get(0);
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});

context('given anyOf keyword with reference', function () {
const schemaElement = SchemaElement.refract({
anyOf: [{ $ref: '#/path/to/schema' }],
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.anyOf?.get(0);
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});

context('given oneOf keyword with reference', function () {
const schemaElement = SchemaElement.refract({
oneOf: [{ $ref: '#/path/to/schema' }],
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.oneOf?.get(0);
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});

context('given dependencies keyword with reference', function () {
const schemaElement = SchemaElement.refract({
dependencies: { dep1: { $ref: '#/path/to/schema' } },
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.dependencies?.get('dep1');
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});

context('given properties keyword with reference', function () {
const schemaElement = SchemaElement.refract({
properties: { prop1: { $ref: '#/path/to/schema' } },
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.properties?.get('prop1');
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});

context('given patternProperties keyword with reference', function () {
const schemaElement = SchemaElement.refract({
patternProperties: { pattern: { $ref: '#/path/to/schema' } },
}) as SchemaElement;

specify('should refract to semantic ApiDOM tree', function () {
expect(sexprs(schemaElement)).toMatchSnapshot();
});

specify('should contain referenced-element meta', function () {
const referenceElement = schemaElement.patternProperties?.get('pattern');
const referencedElementMeta = referenceElement?.getMetaProperty('referenced-element');

assert.strictEqual(referencedElementMeta.toValue(), 'schema');
});
});
});
});
});

0 comments on commit d7cc458

Please sign in to comment.