Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

Commit

Permalink
feat(oas3): support multiple types in Schema Object
Browse files Browse the repository at this point in the history
  • Loading branch information
kylef committed Feb 23, 2021
1 parent f781a34 commit 2e47835
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
24 changes: 12 additions & 12 deletions packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function constructArrayStructure(namespace, schema) {
return element;
}

function constructStructure(namespace, schema, type) {
const constructStructure = R.curry((namespace, schema, type) => {
let element;

if (type === 'object') {
Expand All @@ -106,7 +106,7 @@ function constructStructure(namespace, schema, type) {
}

return element;
}
});

const openapi30Types = ['boolean', 'object', 'array', 'number', 'string', 'integer'];
const openapi31Types = openapi30Types.concat(['null']);
Expand Down Expand Up @@ -189,13 +189,7 @@ function parseType(context) {
const parseArrayType = pipeParseResult(namespace,
R.when(isEmpty, createWarning(namespace, `'${name}' 'type' array must contain at least one type`)),
parseArray(context, `${name}' 'type`, parseArrayTypeItem),
ensureTypesAreUnique,

// FIXME support >1 type
R.unless(
e => e.length === 0 || e.length === 1 || (e.length === 2 && e.contains('null')),
createWarning(namespace, `'${name}' 'type' more than one type is current unsupported`)
));
ensureTypesAreUnique);

return R.cond([
[isString, parseStringType],
Expand Down Expand Up @@ -385,11 +379,17 @@ function parseSchema(context) {
element = constValue;
} else if (enumerations) {
element = enumerations;
} else if (type.length === 1 || (type.length === 2 && type.includes('null'))) {
const findType = R.find(R.complement(R.equals('nullable')));
} else if (type.length === 1) {
element = constructStructure(namespace, schema, type[0]);
} else if (type.length === 2 && type.includes('null')) {
const findType = R.find(R.complement(R.equals('null')));
element = constructStructure(namespace, schema, findType(type));
} else if (type.length > 1) {
throw new Error('Implementation error: unexpected multiple types');
const removeNull = R.filter(R.complement(R.equals('null')));
const types = removeNull(type);

element = new namespace.elements.Enum();
element.enumerations = R.map(constructStructure(namespace, schema), types);
} else {
element = new namespace.elements.Enum();
element.enumerations = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,6 @@ describe('Schema Object', () => {
);
});

it('warns when array items contain more than 1 entry', () => {
// FIXME support more than one entry :)
const schema = new namespace.elements.Object({
type: ['string', 'number'],
});
const parseResult = parse(context, schema);

expect(parseResult).to.contain.warning(
"'Schema Object' 'type' more than one type is current unsupported"
);
});

it('when type contains a single value', () => {
const schema = new namespace.elements.Object({
type: ['string'],
Expand Down Expand Up @@ -308,6 +296,44 @@ describe('Schema Object', () => {
expect(string).to.be.instanceof(namespace.elements.String);
expect(string.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']);
});

it('when type contains multiple values', () => {
const schema = new namespace.elements.Object({
type: ['string', 'number'],
});
const parseResult = parse(context, schema);

expect(parseResult.length).to.equal(1);
expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure);
expect(parseResult).to.not.contain.annotations;

const element = parseResult.get(0).content;
expect(element).to.be.instanceof(namespace.elements.Enum);

expect(element.enumerations.length).to.equal(2);
expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String);
expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number);
expect(element.attributes.getValue('typeAttributes')).to.be.undefined;
});

it('when type contains multiple values with null', () => {
const schema = new namespace.elements.Object({
type: ['string', 'number', 'null'],
});
const parseResult = parse(context, schema);

expect(parseResult.length).to.equal(1);
expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure);
expect(parseResult).to.not.contain.annotations;

const element = parseResult.get(0).content;
expect(element).to.be.instanceof(namespace.elements.Enum);

expect(element.enumerations.length).to.equal(2);
expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String);
expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number);
expect(element.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']);
});
});
});

Expand Down

0 comments on commit 2e47835

Please sign in to comment.