Skip to content

Commit

Permalink
feat(oas2): support additionalProperties with subschema
Browse files Browse the repository at this point in the history
  • Loading branch information
kylef committed Feb 23, 2021
1 parent fd2584f commit f4d25cd
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 4 deletions.
19 changes: 16 additions & 3 deletions packages/openapi2-parser/lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,29 @@ class DataStructureGenerator {
// Create member elements for required keys which are not defined in properties
const missingRequiredProperties = required.filter(name => properties[name] === undefined);
const requiredMembers = missingRequiredProperties.map((name) => {
const member = new this.minim.elements.Member(name);
let member;

if (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== 'boolean') {
member = this.generateMember(name, schema.additionalProperties);
} else {
member = new this.minim.elements.Member(name);
}

member.attributes.set('typeAttributes', ['required']);
return member;
});
element.content.push(...requiredMembers);

if (schema.additionalProperties === false) {
if (schema.additionalProperties !== undefined && schema.additionalProperties !== true) {
const typeAttributes = element.attributes.get('typeAttributes') || new this.minim.elements.Array([]);
typeAttributes.push('fixed-type');
typeAttributes.push('fixedType');
element.attributes.set('typeAttributes', typeAttributes);

if (schema.additionalProperties !== false) {
const member = this.generateMember('', schema.additionalProperties);
member.attributes.set('variable', true);
element.content.push(member);
}
}

return element;
Expand Down
85 changes: 84 additions & 1 deletion packages/openapi2-parser/test/schema-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,90 @@ describe('JSON Schema to Data Structure', () => {
expect(dataStructure.content).to.be.instanceof(ObjectElement);

expect(dataStructure.content.length).to.equal(0);
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixed-type']);
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
});

it('produces object with additionalProperties as false with required properties', () => {
const schema = {
type: 'object',
required: ['type'],
additionalProperties: false,
};

const dataStructure = schemaToDataStructure(schema);

expect(dataStructure.element).to.equal('dataStructure');
expect(dataStructure.content).to.be.instanceof(ObjectElement);

expect(dataStructure.content.length).to.equal(1);
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);

const type = dataStructure.content.getMember('type');
expect(type).to.be.instanceof(MemberElement);
expect(type.attributes.getValue('variable')).to.be.undefined;
expect(type.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
expect(type.value).to.be.undefined;
});

it('produces object with additionalProperties containing a structure', () => {
const schema = {
type: 'object',
additionalProperties: {
type: 'string',
},
};

const dataStructure = schemaToDataStructure(schema);

expect(dataStructure.element).to.equal('dataStructure');
expect(dataStructure.content).to.be.instanceof(ObjectElement);

expect(dataStructure.content.length).to.equal(1);

const member = dataStructure.content.getMember('');
expect(member).to.be.instanceof(MemberElement);
expect(member.attributes.getValue('variable')).to.be.true;
expect(member.value).to.be.instanceof(StringElement);

expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
});

it('produces object with required additionalProperties containing a structure', () => {
const schema = {
type: 'object',
additionalProperties: {
type: 'string',
},
required: ['type', 'mode'],
};

const dataStructure = schemaToDataStructure(schema);

expect(dataStructure.element).to.equal('dataStructure');
expect(dataStructure.content).to.be.instanceof(ObjectElement);
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);

expect(dataStructure.content.length).to.equal(3);

// Variable property
const variable = dataStructure.content.getMember('');
expect(variable).to.be.instanceof(MemberElement);
expect(variable.attributes.getValue('variable')).to.be.true;
expect(variable.value).to.be.instanceof(StringElement);

// Required 'type' property
const type = dataStructure.content.getMember('type');
expect(type).to.be.instanceof(MemberElement);
expect(type.attributes.getValue('variable')).to.be.undefined;
expect(type.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
expect(type.value).to.be.instanceof(StringElement);

// Required 'mode' property
const mode = dataStructure.content.getMember('mode');
expect(mode).to.be.instanceof(MemberElement);
expect(mode.attributes.getValue('variable')).to.be.undefined;
expect(mode.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
expect(mode.value).to.be.instanceof(StringElement);
});
});

Expand Down

0 comments on commit f4d25cd

Please sign in to comment.