From 6197f8d9d52f5b19d45ba13a893d879d4068d818 Mon Sep 17 00:00:00 2001 From: Patrick Silva Date: Tue, 8 Sep 2020 13:13:58 +0200 Subject: [PATCH] fix(core): prefer sample/default over undefined props (#556) Prefer sample/default over Object with undefined property values --- packages/api-elements/CHANGELOG.md | 7 +++++ packages/api-elements/lib/define-value-of.js | 8 ++++-- packages/api-elements/package.json | 2 +- packages/api-elements/test/value-of-test.js | 28 ++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/api-elements/CHANGELOG.md b/packages/api-elements/CHANGELOG.md index 45b6eee00..42ead9e4b 100644 --- a/packages/api-elements/CHANGELOG.md +++ b/packages/api-elements/CHANGELOG.md @@ -1,5 +1,12 @@ # API Elements (JavaScript) CHANGELOG +## 0.3.1 (2020-09-07) + +### Bug Fixes + +- Generating a value from an element will now prefer sample/default values for + objects which contain only undefined property values. + ## 0.3.0 (2020-08-05) ### Bug Fixes diff --git a/packages/api-elements/lib/define-value-of.js b/packages/api-elements/lib/define-value-of.js index 01add0808..f7866c00b 100644 --- a/packages/api-elements/lib/define-value-of.js +++ b/packages/api-elements/lib/define-value-of.js @@ -86,6 +86,7 @@ function findFirstSample(e) { const isPrimitive = e => (e instanceof StringElement) || (e instanceof NumberElement) || (e instanceof BooleanElement); const isEnumElement = e => e instanceof EnumElement; const isArrayElement = e => e instanceof ArrayElement; +const isObjectElement = e => e instanceof ObjectElement; const hasSample = e => findFirstSample(e) !== null; const hasDefault = e => findDefault(e) !== null; @@ -94,6 +95,9 @@ const hasValue = R.anyPass([hasContent, hasSample, hasDefault]); const hasNoValue = R.complement(hasValue); const isNoValuePrimitive = R.both(isPrimitive, hasNoValue); const isNonEmptyArrayElement = e => isArrayElement(e) && e.content && !e.isEmpty; +const isEmptyArray = e => isArrayElement(e) && e.content.every(isNoValuePrimitive); +const isObjectWithUndefinedValues = e => isObjectElement(e) + && e.content.every(prop => prop.value === undefined || prop.value.content === undefined); function trivialValue(e) { @@ -123,7 +127,7 @@ function mapValue(e, options, f, elements) { const opts = updateTypeAttributes(e, options); - if (e.content && !(isArrayElement(e) && e.content.every(isNoValuePrimitive))) { + if (e.content && !isEmptyArray(e) && !isObjectWithUndefinedValues(e)) { const result = f(e, opts, elements, 'content'); if (undefined !== result) { @@ -226,7 +230,7 @@ function reduceValue(e, options, elements) { return mapValue(e.content, inheritFlags(opts), reduceValue, elements); } - if (e instanceof ObjectElement) { + if (isObjectElement(e)) { let result = {}; const isFixed = isFlag(FIXED_FLAG, opts); diff --git a/packages/api-elements/package.json b/packages/api-elements/package.json index 61b894809..b4998ec33 100644 --- a/packages/api-elements/package.json +++ b/packages/api-elements/package.json @@ -1,6 +1,6 @@ { "name": "api-elements", - "version": "0.3.0", + "version": "0.3.1", "description": "API Elements JavaScript", "author": "Apiary.io ", "license": "MIT", diff --git a/packages/api-elements/test/value-of-test.js b/packages/api-elements/test/value-of-test.js index 621de08a2..502b40efb 100644 --- a/packages/api-elements/test/value-of-test.js +++ b/packages/api-elements/test/value-of-test.js @@ -968,6 +968,34 @@ describe('valueOf ObjectElement', () => { expect(value).to.deep.equal({ gaga: 'bing' }); }); + it('prefers samples over undefined property values', () => { + const element = new ObjectElement({ key1: new StringElement(), key2: new StringElement() }); + element.attributes.set('default', new ObjectElement({ key1: 'defaultValue', key2: 'otherDefaultValue' })); + element.attributes.set('samples', new ArrayElement([ + new ObjectElement({ key1: 'sampleValue', key2: 'otherSampleValue' }), + ])); + const value = element.valueOf(); + + expect(value).to.deep.equal({ key1: 'sampleValue', key2: 'otherSampleValue' }); + }); + + it.only('prefers default over undefined property values', () => { + const defaults = new ObjectElement({ key1: 'defaultValue', key2: 'otherDefaultValue' }); + + const element1 = new ObjectElement({ key1: new StringElement(), key2: new StringElement() }); + element1.attributes.set('default', defaults); + const value1 = element1.valueOf(); + + const element2 = new ObjectElement([ + new MemberElement(), new MemberElement(), + ]); + element2.attributes.set('default', defaults); + const value2 = element2.valueOf(); + + expect(value1).to.deep.equal({ key1: 'defaultValue', key2: 'otherDefaultValue' }); + expect(value2).to.deep.equal({ key1: 'defaultValue', key2: 'otherDefaultValue' }); + }); + it('generates {} if no content, default, samples and not nullable', () => { const element = new ObjectElement(); const value = element.valueOf();