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

Support multiple types in Schema Object #606

Merged
merged 1 commit into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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