From e3b1848afe1c6c34568e692731e0a9633ba53368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Gorej?= Date: Sat, 24 Feb 2024 14:49:36 +0100 Subject: [PATCH] fix(ns-asyncapi-2): retain meta & attributes during refracting (#3858) This change is specific to cases when semantic ApiDOM is refractored from generic ApiDOM. Refs #3842 --- .../src/refractor/visitors/Visitor.ts | 17 +++++++--- .../Reference/__snapshots__/index.ts.snap | 7 ++++ .../refractor/elements/Reference/index.ts | 32 +++++++++++++++++-- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/apidom-ns-asyncapi-2/src/refractor/visitors/Visitor.ts b/packages/apidom-ns-asyncapi-2/src/refractor/visitors/Visitor.ts index 013675e53..36fa4100c 100644 --- a/packages/apidom-ns-asyncapi-2/src/refractor/visitors/Visitor.ts +++ b/packages/apidom-ns-asyncapi-2/src/refractor/visitors/Visitor.ts @@ -1,4 +1,4 @@ -import { Element, hasElementSourceMap } from '@swagger-api/apidom-core'; +import { Element, ObjectElement, deepmerge, hasElementSourceMap } from '@swagger-api/apidom-core'; export interface VisitorOptions {} @@ -9,13 +9,20 @@ class Visitor { Object.assign(this, options); } - // eslint-disable-next-line class-methods-use-this + /* eslint-disable class-methods-use-this, no-param-reassign */ public copyMetaAndAttributes(from: Element, to: Element) { - // copy sourcemaps - if (hasElementSourceMap(from)) { - to.meta.set('sourceMap', from.meta.get('sourceMap')); + if (from.meta.length > 0 || to.meta.length > 0) { + to.meta = deepmerge(to.meta, from.meta) as ObjectElement; + if (hasElementSourceMap(from)) { + // avoid deep merging of source maps + to.meta.set('sourceMap', from.meta.get('sourceMap')); + } + } + if (from.attributes.length > 0 || from.meta.length > 0) { + to.attributes = deepmerge(to.attributes, from.attributes) as ObjectElement; // eslint-disable-line no-param-reassign } } + /* eslint-enable- class-methods-use-this, no-param-reassign */ } export default Visitor; diff --git a/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/__snapshots__/index.ts.snap b/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/__snapshots__/index.ts.snap index 9c3b4fc61..c474f010c 100644 --- a/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/__snapshots__/index.ts.snap +++ b/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/__snapshots__/index.ts.snap @@ -1,5 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`refractor elements ReferenceElement given generic ApiDOM element should refract to semantic ApiDOM tree 1`] = ` +(ReferenceElement + (MemberElement + (StringElement) + (StringElement))) +`; + exports[`refractor elements ReferenceElement should refract to semantic ApiDOM tree 1`] = ` (ReferenceElement (MemberElement diff --git a/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/index.ts b/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/index.ts index e454e2dba..625bbb5b2 100644 --- a/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/index.ts +++ b/packages/apidom-ns-asyncapi-2/test/refractor/elements/Reference/index.ts @@ -1,5 +1,5 @@ -import { expect } from 'chai'; -import { sexprs } from '@swagger-api/apidom-core'; +import { assert, expect } from 'chai'; +import { ObjectElement, sexprs, toValue } from '@swagger-api/apidom-core'; import { ReferenceElement } from '../../../../src'; @@ -13,6 +13,34 @@ describe('refractor', function () { expect(sexprs(referenceElement)).toMatchSnapshot(); }); + + context('given generic ApiDOM element', function () { + let referenceElement: ReferenceElement; + + beforeEach(function () { + referenceElement = ReferenceElement.refract( + new ObjectElement( + { $ref: '#/path/to/somewhere' }, + { classes: ['example'] }, + { attr: true }, + ), + ) as ReferenceElement; + }); + + specify('should refract to semantic ApiDOM tree', function () { + expect(sexprs(referenceElement)).toMatchSnapshot(); + }); + + specify('should deepmerge meta', function () { + assert.deepEqual(toValue(referenceElement.meta), { + classes: ['json-reference', 'asyncapi-reference', 'example', 'reference-element'], + }); + }); + + specify('should deepmerge attributes', function () { + assert.isTrue(referenceElement.attributes.get('attr').equals(true)); + }); + }); }); }); });